package com.gitee.dufafei.plugin.vfs.config;

import com.gitee.dufafei.plugin.variable.VariableSpace;
import org.apache.commons.vfs2.FileSystemOptions;

import java.io.IOException;
import java.lang.reflect.Method;

public class FileSystemConfigFactory {

    private FileSystemConfigFactory() {}

    public static FileSystemConfigInterface getConfigBuilder(String scheme, VariableSpace varSpace) throws IOException {
        FileSystemConfigInterface result;
        String parserClass = varSpace.getVariable("vfs." + scheme + ".config.parser");
        if (parserClass != null) {
            try {
                Class<?> configBuilderClass = FileSystemConfigFactory.class.getClassLoader().loadClass(parserClass);
                Method mGetInstance = configBuilderClass.getMethod("getInstance");
                if (mGetInstance != null
                        && FileSystemConfigInterface.class.isAssignableFrom(mGetInstance.getReturnType())) {
                    result = (FileSystemConfigInterface) mGetInstance.invoke( null );
                } else {
                    result = (FileSystemConfigInterface) configBuilderClass.newInstance();
                }
            } catch (Exception e) {
                throw new IOException("Failed to load custom vfs settings parser", e);
            }
        } else {
            result = new GenericFileSystemConfigBuilder();
        }
        return result;
    }

    public static FileSystemOptions buildFsOptions(String vfsFilename,
                                                   String scheme,
                                                   FileSystemOptions sourceOptions,
                                                   VariableSpace varSpace) throws IOException {
        if (vfsFilename == null || varSpace == null) {
            return null;
        }
        FileSystemOptions fsOptions = (sourceOptions == null) ? new FileSystemOptions() : sourceOptions;
        FileSystemConfigInterface configBuilder = getConfigBuilder(scheme, varSpace);
        String[] varList = varSpace.listVariables();
        String prefix = "vfs." + scheme + ".";
        for (String var : varList) {
            if (var.startsWith(prefix)) {
                String key = configBuilder.parseParameterName(var.replace(prefix, ""));
                if (key != null) {
                    configBuilder.setParameter(fsOptions, scheme, key, varSpace.getVariable(var));
                } else {
                    throw new IOException("FileSystemConfig could not parse parameter: " + var);
                }
            }
        }
        return fsOptions;
    }
}
